package com.faceye.core.service.export.excel.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.faceye.core.service.export.excel.ExcelService;
import com.faceye.core.service.export.excel.data.DCell;
import com.faceye.core.service.export.excel.data.DRecord;
import com.faceye.core.service.export.excel.data.DSheet;

/**
 * 将数据导出到Excel
 * 
 * @author songhaipeng
 *
 */
@Service
public class ExcelServiceImpl implements ExcelService {

	private Logger logger = LoggerFactory.getLogger(ExcelServiceImpl.class);
	private DecimalFormat decimalFormat = new DecimalFormat("##.####");

	/**
	 * 导出excel
	 */
	public void export(OutputStream stream, DSheet... dsheets) {

		HSSFWorkbook workbook = this.buildHSSFWorkbook(dsheets);
		try {
			if (stream == null) {
				stream = this.getDefaultOutputStream();
			}
			workbook.write(stream);
		} catch (FileNotFoundException e) {
			logger.error(">>Exception:" + e);
		} catch (IOException e) {
			logger.error(">>Exception:" + e);
		} finally {
			if (stream != null) {
				try {
					stream.flush();
					stream.close();
				} catch (IOException e) {
					logger.error(">>Exception:" + e);
				}
			}
		}
	}

	private HSSFWorkbook buildHSSFWorkbook(DSheet... dsheets) {
		// 创建工作薄
		HSSFWorkbook workbook = new HSSFWorkbook();
		if (dsheets != null) {
			for (DSheet dsheet : dsheets) {
				this.buildHSSFSheet(workbook, dsheet);
			}
		}
		return workbook;
	}

	/**
	 * 构建 HSSFSheet
	 * 
	 * @param workbook
	 * @param dsheet
	 * @Desc:
	 * @Author:haipenge
	 * @Date:2019年11月16日 下午5:12:44
	 */
	private void buildHSSFSheet(HSSFWorkbook workbook, DSheet dsheet) {
		// 创建工作表
		HSSFSheet sheet = workbook.createSheet(dsheet.getSheetName());

		HSSFCellStyle defaultDataCellStyle = this.buildCellStyle(workbook, (short) 11, false, HSSFColor.BLACK.index);
		HSSFCellStyle miniFontSizeStyle = this.buildCellStyle(workbook, (short) 9, false, HSSFColor.GREY_50_PERCENT.index);
		HSSFCellStyle headerCellStyle = this.buildCellStyle(workbook, (short) 11, true, HSSFColor.BLACK.index);

		// 构建表头
		int rowIndex = 0;
		HSSFRow rowHeader = sheet.createRow(rowIndex);
		// rowHeader.setHeight(new Short("30"));
		rowHeader.setHeightInPoints(20);

		for (int i = 0; i < dsheet.getHeader().getHeaders().size(); i++) {
			String value = "";
			DCell dHeader = dsheet.getHeader().getHeaders().get(i);
			if (dHeader.getV() != null) {
				value = dHeader.getV().toString();
			}
			HSSFCell headerCell = rowHeader.createCell(i);
			if (dHeader.getIsHeader()) {
				headerCell.setCellStyle(headerCellStyle);
			} else {
				headerCell.setCellStyle(defaultDataCellStyle);
			}
			headerCell.setCellValue(value);
			if (i == 0) {
				sheet.setColumnWidth(i, 25 * 256);
			} else {
				sheet.setColumnWidth(i, 15 * 256);
			}
		}
		rowIndex++;
		// 向sheet填充数据
		for (int i = 0; i < dsheet.getRecords().size(); i++) {
			HSSFRow row = sheet.createRow(rowIndex);
			DRecord dRecord = dsheet.getRecords().get(i);
			if (dRecord.getCells().get(0).isUseMiniFontSize()) {
				row.setHeightInPoints(14);
			} else {
				row.setHeightInPoints(20);
			}
			for (int j = 0; j < dRecord.getCells().size(); j++) {
				DCell dCell = dRecord.getCells().get(j);
				String value = "";
				if (dCell != null && dCell.getV() != null) {
					value = dCell.getV().toString();
				}
				HSSFCell cell = row.createCell(j);
				if (dCell.getIsHeader()) {
					if (dCell.isUseMiniFontSize()) {
						cell.setCellStyle(miniFontSizeStyle);
					} else {
						cell.setCellStyle(headerCellStyle);
					}
				} else {
					if (dCell.isUseMiniFontSize()) {
						cell.setCellStyle(miniFontSizeStyle);
					} else {
						cell.setCellStyle(defaultDataCellStyle);
					}
				}
				if(!dCell.getFormula()) {
					cell.setCellValue(value);
				}else{
					//如果单元格是公式
					cell.setCellFormula(value);
				}
			}
			rowIndex++;
		}
	}

	/**
	 * 单元格样式
	 * 
	 * @param workbook
	 * @return
	 * @Desc:
	 * @Author:haipenge
	 * @Date:2019年11月16日 下午5:14:13
	 */

	private HSSFCellStyle buildCellStyle(HSSFWorkbook workbook, short fontSize, Boolean isBold, short fontColor) {
		HSSFCellStyle style = workbook.createCellStyle();
		style.setBorderLeft(BorderStyle.DOTTED);
		style.setBorderBottom(BorderStyle.DOTTED);
		style.setBorderRight(BorderStyle.DOTTED);
		style.setBorderTop(BorderStyle.DOTTED);
		style.setAlignment(HorizontalAlignment.RIGHT);
		style.setVerticalAlignment(VerticalAlignment.CENTER);
		// style.setFillBackgroundColor(HSSFColor.ORANGE.index);
		if (false) {
			//设置单元格背景颜色
			style.setFillForegroundColor(HSSFColor.ORANGE.index);
			style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		}
		// 生成一个字体
		HSSFFont font = workbook.createFont();
		font.setColor(fontColor);// HSSFColor.VIOLET.index //字体颜色
		font.setFontHeightInPoints(fontSize);
		font.setBold(isBold);
		style.setFont(font);
		// style.setFillBackgroundColor(HSSFColor.AQUA.index);
		// style.setFillBackgroundColor(HSSFColor.ROYAL_BLUE.index);
		// style.setFillBackgroundColor(HSSFColor.ORANGE.index);

		// style.setFillPattern(CellStyle.);

		return style;
	}

	/**
	 * 导出数据到excel
	 */
	public void export(DSheet dsheet) {
		OutputStream stream = this.getDefaultOutputStream();
		this.export(stream, dsheet);
	}

	private OutputStream getDefaultOutputStream() {
		File xlsFile = new File("d:/poi.xls");
		FileOutputStream stream = null;
		try {
			stream = new FileOutputStream(xlsFile);
		} catch (FileNotFoundException e) {
			logger.error(">>Exception:" + e);
		}
		return stream;
	}

}
